home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d21 / pc_ipc.arc / IPCSAMP.ASM < prev    next >
Assembly Source File  |  1989-12-03  |  9KB  |  275 lines

  1. page 60,132
  2.  
  3. ;PROGRAM : IPCSAMP.ASM
  4. ;      This program demonstrates the use of IPC in Assembly. It is
  5. ;    self-contained in that it makes no references to external data
  6. ;    or procedures. This sample was tested with Microsoft MACRO
  7. ;    Assembler, version 1.27, and Borland Turbo Link, version 1.1,
  8. ;    as follows:
  9. ;        masm ipcsamp.asm, ipcsamp.obj, ipcsamp.lst, ipcsamp.crf
  10. ;        tlink /m /s /n /d /c ipcsamp.obj,ipcsamp.exe,ipcsamp.map
  11. ;        ipcsamp [data]
  12. ;
  13. ;    IPCSAMP initially determines whether IPC is installed by two steps.
  14. ;    First, if IPC's default interrupt vector (60h) is 0000:0000, IPC is
  15. ;    not installed. Second, a call is made to the interrupt routine and
  16. ;    the value returned in param.status is checked. If status is not
  17. ;    INSTALLED and ENABLED, IPC is not installed.
  18. ;
  19. ;    IPCSAMP next checks the command line for data to be passed to IPC.
  20. ;    If no data is present, a default string is used.
  21. ;
  22. ;    The data is sent to IPC and the return status checked. If no errors
  23. ;    occured, the data is retrieved and displayed on the standard output.
  24. ;
  25.  
  26.     ;EQUATES
  27. S_ID        EQU    0        ; sending process id
  28. R_ID        EQU    0        ; receiving process id
  29. CMND_INQ    EQU    1        ; IPC_CMND_INQUIRE
  30. CMND_RDATA    EQU    6        ; IPC_CMND_RDATA
  31. CMND_SDATA    EQU    7        ; IPC_CMND_SDATA
  32. IPC_VECTOR    EQU    60h        ; use default IPC vector
  33. ERROR_FLAG    EQU    8        ; mask for return status
  34. INST_ENAB    EQU    6        ; installed, enabled flags
  35. ERR_NOTINST    EQU    12        ; IPC_ERR_NOTINST
  36. CMND_LEN_OFF    EQU    080h        ; offset of command length
  37. CMND_OFF    EQU    081h        ; offset of command
  38. CMND_LEN_MAX    EQU    07Fh        ; max command length
  39. IRET_INST    EQU    0CFh        ; iret instruction
  40. DOS_PRINT    EQU    9        ; DOS print function
  41. TERM_PROC    EQU    04Ch        ; DOS terminate process function
  42. DOS_CALL    EQU    021h        ; DOS interrupt
  43. GET_VECT    EQU    035h        ; DOS get interrupt vector
  44.  
  45. dataseg    segment                ;define data segment
  46.     IPC_PARAM_BLOCK        struc    ;define IPC_PARAM_BLOCK structure
  47.         my_id        DW    ?
  48.         to_id        DW    ?
  49.         command        DW    ?
  50.         status        DW    ?
  51.         error        DW    ?
  52.         data_size   DW    ?
  53.         data_ptr    DD    ?
  54.     IPC_PARAM_BLOCK        ends
  55.     param    IPC_PARAM_BLOCK    <0,0,0,0,0,0,0>    ; var of type IPC_PARAM_BLOCK
  56.  
  57.                     ;declare a data buffer of 128 bytes
  58.     buf_struct    struc
  59.         string    DB  CMND_LEN_MAX+1  dup (0)
  60.     buf_struct    ends
  61.     buffer buf_struct <>
  62.  
  63.                     ; declare a string of default data
  64.     my_data    DB    "Toto, I don't think we're in Kansas anymore!", 13
  65.     str_length DW     45        ; string length
  66.  
  67.                     ; error messages and codes
  68.     badcmnd_str    DB '001: Invalid command.$'
  69.     inst0_str    DB '002: Only process 0 can install / reset PC-IPC.$'
  70.     cantenab_str    DB '003: Only the disabling process can re-enable.$'
  71.     notenab_str    DB '004: IPC is currently disabled.$'
  72.     cantdisab_str    DB '005: This process cannot disable IPC.$'
  73.     badtoid_str    DB '006: The to-process id is not valid.$'
  74.     badfmid_str    DB '007: The from-process id is not valid.$'
  75.     noaddr_str    DB '008: Invalid target address for data.$'
  76.     maxids_str    DB '009: All available process ids are in use.$'
  77.     cantreli_str    DB '010: That process id cannot be relinquished.$'
  78.     nomem_str    DB '011: Insufficient memory available for message.$'
  79.     notinst_str    DB '012: IPC is not installed. Run IPCINST.COM.$'
  80.  
  81.     badcmnd        DW offset badcmnd_str
  82.     inst0        DW offset inst0_str
  83.     cantenab    DW offset cantenab_str
  84.     notenab        DW offset notenab_str
  85.     cantdisab    DW offset cantdisab_str
  86.     badtoid        DW offset badtoid_str
  87.     badfmid        DW offset badfmid_str
  88.     noaddr        DW offset noaddr_str
  89.     maxids        DW offset maxids_str
  90.     cantreli    DW offset cantreli_str
  91.     nomem        DW offset nomem_str
  92.     notinst        DW offset notinst_str
  93. dataseg    ends
  94.  
  95. stakseg    segment    stack                ; define stack segment
  96.     DB    20 dup ('stack   ')
  97. stakseg    ends
  98.  
  99. progseg        segment                ; define code segment
  100. s_data_asm    proc    far            ; declare as a far proc
  101.         assume    cs:progseg, ds:dataseg
  102.  
  103. start:                        ; starting execution address
  104.  
  105. ; set up stack for return to DOS
  106.     push    ds                ; save old data segment
  107.     sub    ax,ax                ; put 0 in AX
  108.     push    ax                ; save it on stack
  109.     push    ds                ; save the PSP segment
  110.  
  111. ; set up data segment
  112.     mov    ax, dataseg
  113.     mov    ds, ax
  114.  
  115. ; verify that IPC is installed
  116.     mov    ah, GET_VECT            ; get the vector,
  117.     mov    al, IPC_VECTOR            ;  returned in ES:BX
  118.     int    dos_call
  119.     mov    ax, es
  120.     cmp    ax, 0                ; if vector is 0000:0000
  121.     jne    inquire_ipc            ;  IPC is not installed
  122.     cmp    bx, 0
  123.     jne    inquire_ipc
  124.  
  125.     pop    ds                ; (to balance stack)
  126.     mov    ax, ERR_NOTINST            ; print error msg and exit
  127.     jmp    err_print
  128.  
  129. inquire_ipc:
  130.     mov    param.command, CMND_INQ        ; init command to inquire
  131.     mov    param.status, 0            ; clear status field
  132.  
  133. ; call IPC, equivalent to pc_ipc(vector, param_ptr)
  134.     push    ds
  135.     mov    ax, offset param.my_id
  136.     push    ax
  137.     int    IPC_VECTOR            ; call IPC
  138.     add    sp, 4                ; clean up stack
  139.  
  140. ; check return status
  141.     mov    ax, param.status        ; check that IPC is
  142.     cmp    ax, INST_ENAB            ;  installed, enabled
  143.     jz    get_params
  144.  
  145.     pop    ds                ; (to balance stack)
  146.     mov    ax, ERR_NOTINST            ; print error msg and exit
  147.     jmp    err_print
  148.  
  149. ; get a copy of the data (if any) from the DOS command line
  150. ;    The command line parameters are located in the Program Segment Prefix
  151. ;    at offset 081h (CMND_OFF). The length of the parameters is at offset
  152. ;    080h (CMND_LEN_OFF). When loaded as an .exe file, the PSP segment is
  153. ;    automatically put in DS and ES by the loader.
  154.  
  155. get_params:
  156.     pop    ds                ; retore PSP segment
  157.     mov    bx, CMND_LEN_OFF        ; get cmnd line length
  158.     xor    cx, cx                ; clear CX
  159.     mov    cl, byte ptr [ds:bx]
  160.     push    ds                ; save PSP segment
  161.     mov    ax, dataseg
  162.     mov     es, ax                ; set up destination segment
  163.     mov     ds, ax                ; set up source segment
  164.     mov    ax, offset buffer
  165.     mov    di, ax                ; set up destination offset
  166.     mov    ax, offset my_data
  167.     mov    si, ax                ; set up source offset
  168.     cmp    cx, 0                ; if length=0, use default data
  169.     jne    get_cmnd_line
  170.  
  171. ; use default data
  172.     pop    ax                ; discard PSP segment
  173.     mov    cx, str_length            ; set up string length
  174.     jmp    move_data
  175.  
  176. get_cmnd_line:                    ; use command line data
  177.     mov    str_length, cx            ; save length for later
  178.     pop    ds                ; set up source segment
  179.     mov    ax, CMND_OFF            ; set up source offset
  180.     mov    si, ax
  181. move_data:
  182.     cld                    ; copy DS:SI --> ES:DI
  183.     rep    movsb                ;  for CX bytes
  184.     xor    al, al                ; null terminate the string
  185.     dec    di
  186.     mov    byte ptr [es:di], al
  187.  
  188. ; initialize the parameter block, equivalent to init_param_block(...)
  189.  
  190. init_param:
  191.     mov    ax, dataseg            ; set DS to dataseg segment
  192.     mov    ds, ax
  193.     mov    param.my_id, S_ID        ; init my_id
  194.     mov    param.to_id, R_ID        ; init to_id
  195.     mov    param.command, CMND_SDATA    ; init command to send data
  196.     mov    ax, str_length
  197.     mov    param.data_size, ax        ; init data_size
  198.     mov    bx, offset param.my_id        ; use BX to index param
  199.     mov    word ptr [bx+12], offset buffer    ; init data_ptr offset
  200.     mov    word ptr [bx+14], ds        ; init data_ptr segment
  201.  
  202. ; send data to IPC
  203.     push    ds
  204.     mov    ax, offset param.my_id
  205.     push    ax
  206.     int    IPC_VECTOR
  207.     add    sp, 4                ; clean up stack
  208.  
  209. ; check for success
  210.     mov    ax, param.error
  211.     mov    bx, param.status
  212.     and    bx, ERROR_FLAG
  213.     jnz    err_print
  214.  
  215. ; now get the data back from IPC
  216. ; initialize parameter block
  217.     mov    param.my_id, S_ID        ; init my_id
  218.     mov    param.command, CMND_RDATA    ; init command to read data
  219.     mov    param.status, 0            ; clear status
  220.     mov    bx, offset param.my_id        ; use BX to index param
  221.     mov    word ptr [bx+12], offset buffer    ; init data_ptr offset
  222.     mov    word ptr [bx+14], ds        ; init data_ptr segment
  223.  
  224. ; get the data
  225.     push    ds
  226.     mov    ax, offset param.my_id
  227.     push    ax
  228.     int    IPC_VECTOR
  229.     add    sp, 4                ; clean up stack
  230.  
  231. ; check for success
  232.     mov    ax, param.error
  233.     mov    bx, param.status
  234.     and    bx, ERROR_FLAG
  235.     jnz    err_print
  236.  
  237. ; display data returned from IPC
  238.     mov    bx, offset buffer
  239.     mov    ax, param.data_size
  240.     add    bx, ax
  241.     mov    ax, '$'                ; $ terminated string
  242.     mov    [bx], ax
  243.     mov    ah, DOS_PRINT            ; display string function
  244.     mov    dx, offset buffer        ; display string at DS:DX
  245.     int    DOS_CALL
  246.     mov    ax, param.error            ; return error in ERRORLEVEL
  247.  
  248. ; return to DOS
  249. done:
  250.     mov    ah, TERM_PROC            ; DOS terminate process func
  251.     int    DOS_CALL            ; al already has return code
  252.  
  253. err_print:
  254.     push    ax                ; save error number
  255.     mov    bx, offset badcmnd        ; get first msg ptr address
  256.     dec    ax                ; use cx to get msg address
  257.     jz    incr_ptr_done
  258.     mov    cx, ax                ; find correct message ptr
  259. incr_ptr:
  260.     add    bx, 2                ; get next pointer's addr
  261.     loop    incr_ptr            ; loop until done
  262. incr_ptr_done:
  263.     mov    ax, dataseg
  264.     mov    ds, ax
  265.     mov    dx, word ptr [ds:bx]        ; get msg pointer
  266.  
  267. print:
  268.     mov    ah, DOS_PRINT            ; display the error msg
  269.     int    DOS_CALL
  270.     pop    ax                ; return error in ERRORLEVEL
  271.     jmp    done
  272. s_data_asm endp                ; end of module
  273. progseg    ends                ; end of code segment
  274.     end    start            ; end of assembly
  275.